home *** CD-ROM | disk | FTP | other *** search
/ Freelog 9 / Freelog009.iso / BAS / Internet / Rtf2Html / Source C / RTFPARSE / RTFREADR.C < prev    next >
C/C++ Source or Header  |  1999-06-27  |  29KB  |  924 lines

  1.   
  2. /*           
  3.  * %%File: rtfreadr.c
  4.  *
  5.  * Copyright (c) 1995-1999 Bertrand LE QUELLEC
  6.  * Copyright (c) 1989-1995 Microsoft Corporation.
  7.  *
  8.  * http://perso.wanadoo.fr/blq
  9.  * blq@wanadoo.fr
  10.  */
  11.  
  12. #include <stdio.h>                                                                                           
  13.  
  14. #ifndef UNIX_SRC
  15. #include <string.h>
  16. #include <ctype.h>
  17. #include <stdlib.h>
  18. #endif
  19.  
  20. #include "html.h"
  21. #include "rtftype.h"
  22. #include "rtfdecl.h"
  23. #include "mparse.h"
  24. #include "rtfparse.h"
  25. #include "rtfchar.h"
  26. #include "rtfhtml.h"
  27.  
  28. #define SOURCE_READ 1
  29. #include "rtfreadr.h"
  30.  
  31.  
  32. static int ct = 0;              /* un compteur */
  33.  
  34.  
  35. /*
  36.  * %%Function: ecPrintChar
  37.  *
  38.  * Send a character to the output file.
  39.  */
  40. int ecPrintChar(int ch)
  41. {           
  42.     char Tab[MLEN*2];
  43.     int i = 0;
  44.     long nbimage = 0L;
  45.     static long oldimage = 0L;
  46.     static int oldCh = 0;
  47.     
  48.     
  49.     if(!flagGO || flagHeader)
  50.         return ecOK;
  51.  
  52.     /* ---------------------------------------------------
  53.      * unfortunately, we don't do a whole lot here as far
  54.      * as layout goes...
  55.      */
  56.     if (flagFootnote > 0)
  57.     {
  58.         /* Sauvegarde des notes de bas de page */
  59.         if (ch != '\n')
  60.         {
  61.             if(carnot+1 < MLEN * 2)
  62.             {
  63.                 Notes[carnot++] = (char)ch;
  64.                 Notes[carnot] = '\0';
  65.             }
  66.         }
  67.  
  68.         return ecOK;
  69.     }
  70.     else if (flagFldrslt)
  71.     {  
  72.         Fldrslt[nbResult++] = (char)ch;
  73.         Fldrslt[nbResult] = '\0';
  74.     }
  75.     else if (flagBKMK)
  76.     {
  77.         lesBkmk[nbBk++] = (char)ch;
  78.         lesBkmk[nbBk] = '\0';
  79.     }    
  80.     else if(flagTableau)
  81.     {
  82.         /* Sauvegarde des cellules du tableau en cours */
  83.         if(carcell+1 < MLEN * 3)
  84.         {
  85.             cellule[carcell++] = (char)ch;
  86.             cellule[carcell] = '\0';
  87.         }
  88.     }
  89.     else if(flagPnText)
  90.     {
  91.         if(nbcar+1 < MLEN * 2)
  92.         {
  93.             if(ch == '\t')
  94.                 lesCar[nbcar++] = ' ';
  95.             else
  96.                 lesCar[nbcar++] = (char)ch;
  97.             
  98.             lesCar[nbcar] = '\0';
  99.         }
  100.  
  101.         return ecOK;
  102.     }   
  103.     else if (niveau)
  104.     {
  105.         /* Pour un affichage HTML du niveau */
  106.         if (ch != '\n')
  107.         {
  108.             if(carniv+1 < MLEN * 2)
  109.             {
  110.                 if(ch == '\t')
  111.                     leNiveau[carniv++] = ' ';
  112.                 else
  113.                     leNiveau[carniv++] = (char)ch;
  114.                 
  115.                 leNiveau[carniv] = '\0';
  116.             }
  117.         }
  118.  
  119.         return ecOK;
  120.     }                
  121.     else if (flagTOC)
  122.     {
  123.         lesCar[nbcar++] = (char)ch;
  124.         lesCar[nbcar] = '\0';
  125.     }
  126.     else 
  127.     { 
  128.         if (flagDD == 0 && tagDD == 1)
  129.         {                         
  130.             tagDD = 0;
  131.             libPrintString(TAG_BR, fpOut);
  132.         }
  133.             
  134.         if(!modeSpecial && (ch == '<' || ch == '>' || ch == '&'))
  135.         {
  136.             sprintf(Tab, "%c", (char)ch);
  137.             fprintf(fpOut, "%s", HexaToHTML(Tab));
  138.             
  139.             return ecOK;
  140.         }
  141.         else
  142.         {              
  143.             if (nbUrl == 0 && ch == 'h') /* 1 */
  144.             {          
  145.                 /* Possibilite d'une adresse W3 */
  146.                 Url[nbUrl++] = (char)ch;
  147.                 Url[nbUrl] = '\0';
  148.                 flagStop = 0;
  149.             }                    
  150.             else if (nbUrl == 1 && oldCh == 'h' && ch == ' ')
  151.             {            
  152.                 putc('h', fpOut);
  153.                 putc(ch, fpOut);
  154.                            
  155.                 flagStop = 0;
  156.                 nbUrl = 0;
  157.                 Url[nbUrl] = '\0';
  158.             }
  159.             else if (nbUrl == 1 && oldCh == 'h' && ch == 't')  /* 2 */
  160.             {
  161.                 /* La probabilite s'accentue */
  162.                 Url[nbUrl++] = (char)ch;
  163.                 Url[nbUrl] = '\0';
  164.                 flagStop = 0;
  165.             }
  166.             else if (nbUrl == 2 && oldCh == 't' && ch == 't') /* 3 */
  167.             {
  168.                 /* La probabilite s'accentue... */
  169.                 Url[nbUrl++] = (char)ch;
  170.                 Url[nbUrl] = '\0';
  171.                 flagStop = 0;
  172.             }
  173.             else if (nbUrl == 3 && oldCh == 't' && ch == 'p') /* 4 */
  174.             {
  175.                 /* La probabilite est presque evidente... */
  176.                 Url[nbUrl++] = (char)ch;
  177.                 Url[nbUrl] = '\0';
  178.                 flagStop = 0;
  179.             }
  180.             else if (nbUrl == 4 && oldCh == 'p' && ch == ':') /* 5 */
  181.             {
  182.                 /* La probabilite est evidente */
  183.                 Url[nbUrl++] = (char)ch;
  184.                 Url[nbUrl] = '\0';
  185.                    oldCh = -10;
  186.                 flagStop = 0;
  187.                 
  188.                 return ecOK;
  189.             }   
  190.             else
  191.             {   
  192.                 if (flagStop || (ch != '/' && ch != ':' && ch != '#' && ch != '~' && ch != '.' && ch != '-' && ch != '_' && !isalnum(ch)))
  193.                 {
  194.                     if (strlen(Url) > 4)
  195.                     {
  196.                         libPrintString(GetHrefHTML2(Url, Url),fpOut);
  197.                     }
  198.                     
  199.                     flagStop = 0;
  200.                     nbUrl = 0;
  201.                     oldCh = 0;
  202.                     Url[nbUrl] = '\0';
  203.                 }
  204.                 
  205.                 if (nbUrl && oldCh == -10)
  206.                 {   
  207.                     Url[nbUrl++] = (char)ch;
  208.                     Url[nbUrl] = '\0';
  209.                     
  210.                     return ecOK;
  211.                 }
  212.                 else
  213.                 {   
  214.                     if(strlen(Url))
  215.                     {
  216.                         /* Annulation adresse W3 */
  217.                         libPrintString(Url, fpOut);
  218.                     }
  219.                                   
  220.                     flagStop = 0;
  221.                     nbUrl = 0;
  222.                     Url[nbUrl] = '\0';
  223.                 }
  224.                         
  225.                 putc(ch, fpOut);
  226.             }
  227.             
  228.             oldCh = ch;
  229.         }
  230.     }
  231.    
  232.     return ecOK;
  233. }
  234.  
  235.  
  236. /*
  237.  * %%Function: ecParseChar
  238.  *
  239.  * Route the character to the appropriate destination stream.
  240.  */
  241. int ecParseChar(int ch)
  242. {
  243.     if (ris == risBin && --cbBin <= 0)
  244.         ris = risNorm;
  245.  
  246.     switch (rds)
  247.     {
  248.         case rdsSkip: /* Toss this character. */
  249.             break;
  250.  
  251.         case rdsNorm:
  252.             /* Output a character.
  253.              * Properties are valid at this point. */
  254.             return ecPrintChar(ch);
  255.  
  256.         default: /* handle other destinations.... */
  257.             break;
  258.     }
  259.  
  260.     return ecOK;
  261. }
  262.  
  263.  
  264. /*
  265.  * %%Function: ecPushRtfState
  266.  *
  267.  * Save relevant info on a linked list of SAVE structures. 
  268.  */
  269. static int ecPushRtfState(void)
  270. {                   
  271. #ifdef UNIX_SRC
  272.     pSAVE psaveNew = (pSAVE)calloc(1, sizeof(SAVE));
  273.                
  274.     if (!psaveNew)
  275.         return ecStackOverflow;
  276. #else  
  277.     HGLOBAL HGLB = GlobalAlloc(GPTR, sizeof(SAVE));
  278.     pSAVE psaveNew = (pSAVE)GlobalLock(HGLB);
  279.     
  280.     if(!HGLB)
  281.         return ecNO;
  282.     
  283.     if(!psaveNew)
  284.         return ecNO;
  285.             
  286.     psaveNew->phandle = HGLB;
  287. #endif
  288.  
  289.     psaveNew->pNext = psave;
  290.     psaveNew->chp = chp;
  291.     psaveNew->pap = pap;
  292.     psaveNew->sep = sep;
  293.     psaveNew->dop = dop;
  294.     psaveNew->rds = rds;
  295.     psaveNew->ris = ris;
  296.  
  297.     psave = psaveNew;
  298.  
  299.     ris = risNorm;
  300.     cGroup++;
  301.  
  302.     return ecOK;
  303. }
  304.  
  305.  
  306. /*
  307.  * %%Function: ecPopRtfState
  308.  *
  309.  * If we're ending a destination (i.e., the destination is changing),
  310.  * call ecEndGroupAction.
  311.  * Always restore relevant info from the top of the SAVE list.
  312.  */
  313. static int ecPopRtfState(void)
  314. {
  315.     int     ec        = 0;
  316.     pSAVE   psaveOld  = (pSAVE)0;
  317.                
  318.                
  319.     if (!psave)
  320.         return ecStackUnderflow;
  321.  
  322.     if (rds != psave->rds)
  323.     {
  324.         if ((ec = ecEndGroupAction(rds)) != ecOK)
  325.             return ec;
  326.     }
  327.     
  328.     chp = psave->chp;
  329.     pap = psave->pap;
  330.     sep = psave->sep;
  331.     dop = psave->dop;
  332.     rds = psave->rds;
  333.     ris = psave->ris;
  334.     
  335.     psaveOld = psave;
  336.     psave = psave->pNext;
  337.     
  338. #ifdef UNIX_SRC    
  339.     free(psaveOld);
  340. #else   
  341.     if(psaveOld->phandle)
  342.     {  
  343.         GlobalUnlock(psaveOld->phandle);
  344.         GlobalFree(psaveOld->phandle);
  345.     }
  346. #endif
  347.  
  348.     cGroup--;
  349.  
  350.     return ecOK;
  351. }
  352.  
  353.  
  354. /* 
  355.  * %%Function: ecParseRtfKeyword
  356.  *
  357.  * Step 2 :
  358.  * get a control word (and it's associated value) and
  359.  * call ecTranslateKeyword to dispatch the control.
  360.  */
  361. static int ecParseRtfKeyword(FILE * fp)
  362. {
  363.     int     ch      = 0;
  364.     char    fParam  = fFalse;
  365.     char    fNeg    = fFalse;
  366.     int     param   = 0;   
  367.     int     flag    = 0;
  368.     char    * pch   = (char *)0;
  369.     char    szKeyword   [30];
  370.     char    szParameter [20];
  371.                   
  372.                   
  373.     szKeyword[0]   = '\0';
  374.     szParameter[0] = '\0'; 
  375.        
  376.     if ((ch = getc(fp)) == EOF)
  377.         return ecEndOfFile;
  378.  
  379.     /* a control symbol ; no delimiter. */
  380.     if (!isalpha(ch) && ch != '\'')
  381.     {
  382.         szKeyword[0] = (char) ch;
  383.         szKeyword[1] = '\0';   
  384.             
  385.         return ecTranslateKeyword((char *)szKeyword, 0, fParam);
  386.     }
  387.  
  388.     /* Caractere special : accent */
  389.     if (ch == '\'') 
  390.     {          
  391.         /* Les caracteres accentues sont stockes sous forme hexa
  392.          * sur deux caracteres apres le code RTF \'
  393.          */           
  394.         flag = 1;
  395.         
  396.         /*  Enregistrement du caractere special quote ' */
  397.         szKeyword[0] = (char) ch;
  398.         szKeyword[1] = '\0';   
  399.         pch = (char *)szKeyword;
  400.  
  401.         if ((ch = getc(fp)) == EOF)
  402.             return ecEndOfFile;
  403.  
  404.         szKeyword[1] = (char) ch;  
  405.                      
  406.         /* Si le second code hexa est un chiffre
  407.          * on le recupere plus loin pour le passer a param
  408.          * si le code est un caractere on le stocke.
  409.          */         
  410.         if ((ch = getc(fp)) == EOF)
  411.             return ecEndOfFile;
  412.  
  413.         szKeyword[2] = '\0';
  414.  
  415.         if (!isdigit(ch))
  416.         {             
  417.             fParam = fFalse;   
  418.             param = ch; 
  419.         }
  420.     }
  421.     else
  422.     {
  423.         for (pch = (char *)szKeyword; isalpha(ch); ch = getc(fp))
  424.             *pch++ = (char) ch;
  425.     
  426.         *pch = '\0';
  427.     }
  428.  
  429.  
  430.     if (ch == '-')
  431.     {
  432.         fNeg = fTrue;
  433.     
  434.         if ((ch = getc(fp)) == EOF)
  435.             return ecEndOfFile;
  436.     }
  437.     
  438.     if (isdigit(ch))
  439.     {
  440.         /* a digit after the control means we have a parameter */
  441.         fParam = fTrue;
  442.                 
  443.         /* Dans le cas d'une detection de caracteres speciaux */
  444.         if (!flag)
  445.         {
  446.             for (pch = (char *)szParameter; isdigit(ch); ch = getc(fp))
  447.                 *pch++ = (char) ch;
  448.         }
  449.         else
  450.         {              
  451.             /* recuperation d'un seul caractere. */
  452.             pch = (char *)szParameter;
  453.             *pch++ = (char) ch;
  454.         }
  455.         
  456.         *pch  = '\0';
  457.         param = atoi(szParameter);
  458.             
  459.         if (fNeg)
  460.             param = -param;
  461.         
  462.         lParam = atol(szParameter);
  463.         
  464.         if (fNeg)
  465.             param = -param;
  466.     }
  467.  
  468.                      
  469.     /* Inutile de renvoyer le caractere special */
  470.     if (ch != ' ' && !flag)
  471.         ungetc(ch, fp);
  472.     
  473.     return ecTranslateKeyword(szKeyword, param, fParam);
  474. }
  475.  
  476.  
  477. /*
  478.  * %%Function: ecRtfParse
  479.  * 
  480.  * Step 1:
  481.  * Isolate RTF keywords and send them to ecParseRtfKeyword;
  482.  * Push and pop state at the start and end of RTF groups;
  483.  * Send text to ecParseChar for further processing.
  484.  */
  485. int ecRtfParse(FILE * fp)
  486. {
  487.     register int ch      = 0, ct;
  488.     register int oldCh   = 0;
  489.     
  490.     int ec      = 0;
  491.     int cNibble = 2;
  492.     int b       = 0;
  493.     int nbtok   = 0;
  494.     int par     = 0;
  495.     int flagTok = 0;
  496.     char token[MLEN * 2], tmp[MLEN];
  497.                
  498.                
  499.     while ((ch = getc(fp)) != EOF)
  500.     {
  501.         if (cGroup < 0)
  502.             return ecStackUnderflow;
  503.        
  504.         /* if we're parsing binary data, handle it directly */
  505.         if (ris == risBin)
  506.         {
  507.             if ((ec = ecParseChar(ch)) != ecOK)
  508.                 return ec;
  509.         }
  510.         else
  511.         {
  512.             switch (ch)
  513.             {
  514.                 case '{':
  515.                     if(flagFootnote > 0)
  516.                         par += 1;
  517.  
  518.                     if(crochet < 0) crochet = 0;
  519.  
  520.                     crochet += 1;
  521.  
  522.                     if ((ec = ecPushRtfState()) != ecOK)
  523.                         return ec;
  524.  
  525.                     break;
  526.                         
  527.                 case '}':
  528.                     if (flagBKMK) 
  529.                     {        
  530.                         /* Detection d'une arrivee d'ancre : insertion d'un point d'arrivee */
  531.                         if (strlen(lesBkmk))
  532.                         {
  533.                             if (strlen(lesBkmk) >= 4)
  534.                             {
  535.                                 if (strncmp(lesBkmk, "_Toc", 4))
  536.                                 {
  537.                                     if(flagTableau)
  538.                                     {
  539.                                         sprintf(tmp, "%s", GetANameHTML2(lesBkmk));
  540.                                         
  541.                                         for (ct = 0; ct < (int)strlen(tmp); ct++)
  542.                                         {
  543.                                             /* Sauvegarde des infos dans la cellule courante du tableau */
  544.                                             if(carcell+1 < MLEN * 3)
  545.                                             {
  546.                                                 cellule[carcell++] = tmp[ct];
  547.                                                 cellule[carcell] = '\0';
  548.                                             }
  549.                                             else
  550.                                                 break;
  551.                                         }
  552.                                     }
  553.                                     else
  554.                                         libPrintString(GetANameHTML2(lesBkmk), fpOut);
  555.                                 }    
  556.                             }
  557.                             else
  558.                             {
  559.                                 if(flagTableau)
  560.                                 { 
  561.                                     sprintf(tmp, "%s", GetANameHTML2(lesBkmk));
  562.                                         
  563.                                     for (ct = 0; ct < (int)strlen(tmp); ct++)
  564.                                     {
  565.                                         /* Sauvegarde des infos dans la cellule courante du tableau */
  566.                                         if(carcell+1 < MLEN * 3)
  567.                                         {
  568.                                             cellule[carcell++] = tmp[ct];
  569.                                             cellule[carcell] = '\0';
  570.                                         }
  571.                                         else
  572.                                             break;
  573.                                     }
  574.                                 }
  575.                                 else
  576.                                     libPrintString(GetANameHTML2(lesBkmk), fpOut);
  577.                             }            
  578.                         }
  579.                         
  580.                         flagBKMK = 0;
  581.                         nbBk = 0;
  582.                         lesBkmk[nbBk] = '\0';
  583.                     }
  584.                     else if (flagFldrslt) 
  585.                     {                  
  586.                         /* Detection d'un renvoie : insertion d'une ancre interne point de dΘpart */
  587.                         if (strlen(Fldrslt))
  588.                         {   
  589.                             if (strlen(lesBkmk))
  590.                             {
  591.                                 if(flagTableau)
  592.                                 {
  593.                                     sprintf(tmp, "%s", GetAHNameHTML2(lesBkmk, Fldrslt));
  594.                                         
  595.                                     for (ct = 0; ct < (int)strlen(tmp); ct++)
  596.                                     {
  597.                                         /* Sauvegarde des infos dans la cellule courante du tableau */
  598.                                         if(carcell+1 < MLEN * 3)
  599.                                         {
  600.                                             cellule[carcell++] = tmp[ct];
  601.                                             cellule[carcell] = '\0';
  602.                                         }
  603.                                         else
  604.                                             break;
  605.                                     }
  606.                                 }
  607.                                 else
  608.                                     libPrintString(GetAHNameHTML2(lesBkmk, Fldrslt), fpOut);
  609.                             }    
  610.                             else
  611.                             {
  612.                                 if(flagTableau)
  613.                                 {    
  614.                                     for (ct = 0; ct < (int)strlen(Fldrslt); ct++)
  615.                                     {
  616.                                         /* Sauvegarde des infos dans la cellule courante du tableau */
  617.                                         if(carcell+1 < MLEN * 3)
  618.                                         {
  619.                                             cellule[carcell++] = Fldrslt[ct];
  620.                                             cellule[carcell] = '\0';
  621.                                         }
  622.                                         else
  623.                                             break;
  624.                                     }
  625.                                 }
  626.                                 else
  627.                                     libPrintString(Fldrslt, fpOut);
  628.                             }    
  629.                         }
  630.                         
  631.                         flagFldrslt = 0;
  632.                         nbResult = nbBk = 0;
  633.                         Fldrslt[nbResult] = lesBkmk[nbBk] = '\0';
  634.                     }  
  635. ;
  636.                     if(flagFldrslt)
  637.                     {
  638.                         flagFldrslt = 0;
  639.                     }
  640.  
  641.                     if(flagFootnote > 0)
  642.                         par -= 1;
  643.  
  644.                     if(par < 0)
  645.                     {
  646.                         par = 0;
  647.                         flagFootnote = -1;
  648.                     }
  649.                     
  650.                     /* Affichage de fin de style eventuel */
  651.                     ecPrintItalicF    (fpOut);
  652.                     ecPrintBoldF    (fpOut);
  653.                     
  654.                     if ((ec = ecPopRtfState()) != ecOK)
  655.                         return ec;
  656.  
  657.                     if(valCrochetH == crochet)
  658.                         flagHeader = 0;
  659.  
  660.                     if(valCrochetF == crochet)
  661.                         valCrochetF = 0;
  662.                         
  663.                     flagREF = 0;
  664.                     crochet -= 1;  
  665.                     break;
  666.                         
  667.                 case '\\':  
  668.                     if ((ec = ecParseRtfKeyword(fp)) != ecOK)
  669.                         return ec;
  670.  
  671.                     break;
  672.                         
  673.                 case 0x0d:
  674.                 case 0x0a:/* cr and lf are noise characters... */
  675.                     break;
  676.                 
  677.                 default:
  678.                     if(crochet)
  679.                     {
  680.                         if(ch == ' ')
  681.                         {
  682.                             token[nbtok] = '\0';
  683.  
  684.                             if(!(strcmp(token, "SYMBOL")) || !(strcmp(token, "symbol")))
  685.                             {
  686.                                 flagTok = 1;
  687.                             }
  688.                             else if(!(strcmp(token, "TOC")))
  689.                             {
  690.                                 flagTok = 0;
  691.                                 flagTOC = 1;
  692.  
  693.                                 ecPrintItalicF    (fpOut);
  694.                             } 
  695.                             else if(!(strcmp(lesBkmk, "REF")))
  696.                             {   
  697.                                 flagREF = 1;
  698.                                 nbBk = 0;
  699.                                 lesBkmk[nbBk] = '\0';
  700.                             }
  701.                             else
  702.                             {
  703.                                 if (flagREF && nbBk)
  704.                                 {                               
  705.                                     flagREF = 0;
  706.                                     nbBk = 0;
  707.                                 }    
  708.                                 else if(flagTok)
  709.                                 {
  710.                                     flagTok = 0;
  711.  
  712.                                     switch(atoi(token))
  713.                                     {
  714.                                         case 35:
  715.                                             libPrintString(TokenToHTML("numbersign"), fpOut);
  716.                                             break;
  717.                                         
  718.                                         case 37:
  719.                                             libPrintString(TokenToHTML("percent"), fpOut);
  720.                                             break;
  721.                                         
  722.                                         case 38:
  723.                                             libPrintString(TokenToHTML("ampersand"), fpOut);
  724.                                             break;
  725.                                         
  726.                                         case 95:
  727.                                             libPrintString(TokenToHTML("underscore"), fpOut);
  728.                                             break;
  729.                                         
  730.                                         case 97:
  731.                                             libPrintString(TokenToHTML("alpha"), fpOut);
  732.                                             break;
  733.                                         
  734.                                         case 98:
  735.                                             libPrintString(TokenToHTML("beta"), fpOut);
  736.                                             break;
  737.                                         
  738.                                         case 171:
  739.                                             libPrintString(TokenToHTML("arrowboth"), fpOut);
  740.                                             break;
  741.                                         
  742.                                         case 172:
  743.                                             libPrintString(TokenToHTML("arrowleft"), fpOut);
  744.                                             break;
  745.                                         
  746.                                         case 174:
  747.                                             libPrintString(TokenToHTML("arrowright"), fpOut);
  748.                                             break;
  749.                                         
  750.                                         case 176:
  751.                                             libPrintString(TokenToHTML("degree"), fpOut);
  752.                                             break;
  753.                                         
  754.                                         case 177:
  755.                                             libPrintString(TokenToHTML("plusminus"), fpOut);
  756.                                             break;
  757.                                         
  758.                                         case 179:
  759.                                             libPrintString(TokenToHTML("greaterequal"), fpOut);
  760.                                             break;
  761.                                         
  762.                                         case 183:
  763.                                             if(!flagTableau)
  764.                                             {
  765.                                                 if (!tagLI)
  766.                                                 {
  767.                                                     tagLI = 1;
  768.     
  769.                                                     libPrintCharStd('\n', fpOut);
  770.                                                     libPrintString(TAG_BQUOTE, fpOut);
  771.                                                     libPrintString(TAG_LI, fpOut);
  772.                                                 }
  773.                                             }
  774.  
  775.                                             break;
  776.                                         
  777.                                         case 184:
  778.                                             libPrintString(TokenToHTML("mathdivise"), fpOut);
  779.                                             break;
  780.                                         
  781.                                         case 185:
  782.                                             libPrintString(TokenToHTML("notequal"), fpOut);
  783.                                             break;
  784.                                         
  785.                                         case 187:
  786.                                             libPrintString(TokenToHTML("tilde"), fpOut);
  787.                                             break;
  788.                                         
  789.                                         case 188:
  790.                                             libPrintString(TokenToHTML("ellipsis"), fpOut);
  791.                                             break;
  792.                                         
  793.                                         case 210:
  794.                                             libPrintString(TokenToHTML("registred"), fpOut);
  795.                                             break;
  796.  
  797.                                         case 211:
  798.                                             libPrintString(TokenToHTML("copyright"), fpOut);
  799.                                             break;
  800.                                         
  801.                                         case 212:
  802.                                         case 228:
  803.                                             libPrintString(TokenToHTML("trademark"), fpOut);
  804.                                             break;
  805.                                         
  806.                                         case 219:
  807.                                             libPrintString(TokenToHTML("arrowdblboth"), fpOut);
  808.                                             break;
  809.                                         
  810.                                         case 220:
  811.                                             libPrintString(TokenToHTML("arrowdblleft"), fpOut);
  812.                                             break;
  813.                                         
  814.                                         case 222:
  815.                                             libPrintString(TokenToHTML("arrowdblright"), fpOut);
  816.                                             break;
  817.                                     }
  818.                                 }
  819.                             }
  820.                             
  821.                             nbtok = 0;
  822.                             token[nbtok] = '\0';
  823.                         }
  824.                         else
  825.                         {
  826.                             if(nbtok+1 < MLEN*2 && (nbtok || flagTok))
  827.                                 token[nbtok++] = ch;
  828.                                                 
  829.                             if (nbBk+1 < MLEN && (nbBk || flagREF) && !flagBKMK)
  830.                             {
  831.                                 lesBkmk[nbBk++] = (char)ch;
  832.                                 lesBkmk[nbBk] = '\0';
  833.                             }
  834.                                                         
  835.                             /* Symbol - symbol - TOK - REF */
  836.                             if(ch == 's' || ch == 'S' || ch == 'T')
  837.                             {
  838.                                 nbtok = 0;
  839.                                 token[nbtok++] = ch;
  840.                             }
  841.                             else if (ch == 'R' && oldCh == ' ')
  842.                             {        
  843.                                 nbBk = 0;
  844.                                 lesBkmk[nbBk++] = (char)ch;
  845.                                 lesBkmk[nbBk] = '\0';
  846.                             }
  847.                         }
  848.                     }
  849.  
  850.                     if (ris == risNorm)
  851.                     {
  852.                         if ((ec = ecParseChar(ch)) != ecOK)
  853.                             return ec;
  854.                     }
  855.                     else
  856.                     {
  857.                         /* parsing hex data */
  858.                         if (ris != risHex)
  859.                             return ecAssertion;
  860.                         
  861.                         b = b << 4;
  862.                         
  863.                         if (isdigit(ch))
  864.                             b += (char) ch - '0';
  865.                         else
  866.                         {
  867.                             if (islower(ch))
  868.                             {
  869.                                 if (ch < 'a' || ch > 'f')
  870.                                     return ecInvalidHex;
  871.  
  872.                                 b += (char) ch - 'a';
  873.                             }
  874.                             else
  875.                             {
  876.                                 if (ch < 'A' || ch > 'F')
  877.                                     return ecInvalidHex;
  878.  
  879.                                 b += (char) ch - 'A';
  880.                             }
  881.                         }
  882.                     
  883.                         cNibble--;
  884.  
  885.                         if (!cNibble)
  886.                         {
  887.                             if ((ec = ecParseChar(ch)) != ecOK)
  888.                                 return ec;
  889.  
  890.                             cNibble = 2;
  891.                             b = 0;
  892.                             ris = risNorm;
  893.                         }
  894.                     } /* end else (ris != risNorm) */
  895.                 
  896.                     break;
  897.             } /* switch */
  898.         } /* else (ris != risBin) */
  899.         
  900.         oldCh = ch;
  901.  
  902.     } /* while */
  903.  
  904.     ecDetectPard();
  905.     ecFootnote();
  906.     
  907.     if (cGroup < 0)
  908.         return ecStackUnderflow;
  909.     
  910.     if (cGroup > 0)
  911.         return ecUnmatchedBrace;
  912.         
  913.     if (flagFRAME)
  914.     {                                      
  915.         libPrintCharStd('\n', fpTable);
  916.         
  917.         for (ec = 0; ec <= oldNiveau; ec++)
  918.             libPrintString(TAGf_UL, fpTable);
  919.     }
  920.  
  921.     return ecOK;
  922. }
  923.  
  924.